home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Winzipper
/
Winzipper_ISO.iso
/
nt4.0 server
/
MONEY.BA_
/
money.bas
Wrap
BASIC Source File
|
1993-03-12
|
46KB
|
1,537 lines
'
' Q B a s i c M O N E Y M A N A G E R
'
' Copyright (C) Microsoft Corporation 1990
'
' The Money Manager is a personal finance manager that allows you
' to enter account transactions while tracking your account balances
' and net worth.
'
' To run this program, press Shift+F5.
'
' To exit QBasic, press Alt, F, X.
'
' To get help on a BASIC keyword, move the cursor to the keyword and press
' F1 or click the right mouse button.
'
'Set default data type to integer for faster operation
DEFINT A-Z
'Sub and function declarations
DECLARE SUB TransactionSummary (item%)
DECLARE SUB LCenter (text$)
DECLARE SUB ScrollUp ()
DECLARE SUB ScrollDown ()
DECLARE SUB Initialize ()
DECLARE SUB Intro ()
DECLARE SUB SparklePause ()
DECLARE SUB Center (row%, text$)
DECLARE SUB FancyCls (dots%, Background%)
DECLARE SUB LoadState ()
DECLARE SUB SaveState ()
DECLARE SUB MenuSystem ()
DECLARE SUB MakeBackup ()
DECLARE SUB RestoreBackup ()
DECLARE SUB Box (Row1%, Col1%, Row2%, Col2%)
DECLARE SUB NetWorthReport ()
DECLARE SUB EditAccounts ()
DECLARE SUB PrintHelpLine (help$)
DECLARE SUB EditTrans (item%)
DECLARE FUNCTION Cvdt$ (X#)
DECLARE FUNCTION Cvst$ (X!)
DECLARE FUNCTION Cvit$ (X%)
DECLARE FUNCTION Menu% (CurrChoiceX%, MaxChoice%, choice$(), ItemRow%(), ItemCol%(), help$(), BarMode%)
DECLARE FUNCTION GetString$ (row%, col%, start$, end$, Vis%, Max%)
DECLARE FUNCTION Trim$ (X$)
'Constants
CONST TRUE = -1
CONST FALSE = NOT TRUE
'User-defined types
TYPE AccountType
Title AS STRING * 20
AType AS STRING * 1
Desc AS STRING * 50
END TYPE
TYPE Recordtype
Date AS STRING * 8
Ref AS STRING * 10
Desc AS STRING * 50
Fig1 AS DOUBLE
Fig2 AS DOUBLE
END TYPE
'Global variables
DIM SHARED account(1 TO 19) AS AccountType 'Stores the 19 account titles
DIM SHARED ColorPref 'Color Preference
DIM SHARED colors(0 TO 20, 1 TO 4) 'Different Colors
DIM SHARED ScrollUpAsm(1 TO 7) 'Assembly Language Routines
DIM SHARED ScrollDownAsm(1 TO 7)
DIM SHARED PrintErr AS INTEGER 'Printer error flag
DEF SEG = 0 ' Turn off CapLock, NumLock and ScrollLock
KeyFlags = PEEK(1047)
POKE 1047, &H0
DEF SEG
'Open money manager data file. If it does not exist in current directory,
' goto error handler to create and initialize it.
ON ERROR GOTO ErrorTrap
OPEN "money.dat" FOR INPUT AS #1
CLOSE
ON ERROR GOTO 0 'Reset error handler
Initialize 'Initialize program
Intro 'Display introduction screen
MenuSystem 'This is the main program
COLOR 7, 0 'Clear screen and end
CLS
DEF SEG = 0 ' Restore CapLock, NumLock and ScrollLock states
POKE 1047, KeyFlags
DEF SEG
END
' Error handler for program
' If data file not found, create and initialize a new one.
ErrorTrap:
SELECT CASE ERR
' If data file not found, create and initialize a new one.
CASE 53
CLOSE
ColorPref = 1
FOR a = 1 TO 19
account(a).Title = ""
account(a).AType = ""
account(a).Desc = ""
NEXT a
SaveState
RESUME
CASE 24, 25
PrintErr = TRUE
Box 8, 13, 14, 69
Center 11, "Printer not responding ... Press Space to continue"
WHILE INKEY$ <> "": WEND
WHILE INKEY$ <> " ": WEND
RESUME NEXT
CASE ELSE
END SELECT
RESUME NEXT
'The following data defines the color schemes available via the main menu.
'
' scrn dots bar back title shdow choice curs cursbk shdow
DATA 0, 7, 15, 7, 0, 7, 0, 15, 0, 0
DATA 1, 9, 12, 3, 0, 1, 15, 0, 7, 0
DATA 3, 15, 13, 1, 14, 3, 15, 0, 7, 0
DATA 7, 12, 15, 4, 14, 0, 15, 15, 1, 0
'The following data is actually a machine language program to
'scroll the screen up or down very fast using a BIOS call.
DATA &HB8,&H01,&H06,&HB9,&H01,&H04,&HBA,&H4E,&H16,&HB7,&H00,&HCD,&H10,&HCB
DATA &HB8,&H01,&H07,&HB9,&H01,&H04,&HBA,&H4E,&H16,&HB7,&H00,&HCD,&H10,&HCB
'Box:
' Draw a box on the screen between the given coordinates.
SUB Box (Row1, Col1, Row2, Col2) STATIC
BoxWidth = Col2 - Col1 + 1
LOCATE Row1, Col1
PRINT "┌"; STRING$(BoxWidth - 2, "─"); "┐";
FOR a = Row1 + 1 TO Row2 - 1
LOCATE a, Col1
PRINT "│"; SPACE$(BoxWidth - 2); "│";
NEXT a
LOCATE Row2, Col1
PRINT "└"; STRING$(BoxWidth - 2, "─"); "┘";
END SUB
'Center:
' Center text on the given row.
SUB Center (row, text$)
LOCATE row, 41 - LEN(text$) / 2
PRINT text$;
END SUB
'Cvdt$:
' Convert a double precision number to a string WITHOUT a leading space.
FUNCTION Cvdt$ (X#)
Cvdt$ = RIGHT$(STR$(X#), LEN(STR$(X#)) - 1)
END FUNCTION
'Cvit$:
' Convert an integer to a string WITHOUT a leading space.
FUNCTION Cvit$ (X)
Cvit$ = RIGHT$(STR$(X), LEN(STR$(X)) - 1)
END FUNCTION
'Cvst$:
' Convert a single precision number to a string WITHOUT a leading space
FUNCTION Cvst$ (X!)
Cvst$ = RIGHT$(STR$(X!), LEN(STR$(X!)) - 1)
END FUNCTION
'EditAccounts:
' This is the full-screen editor which allows you to change your account
' titles and descriptions
SUB EditAccounts
'Information about each column
REDIM help$(4), col(4), Vis(4), Max(4), edit$(19, 3)
'Draw the screen
COLOR colors(7, ColorPref), colors(4, ColorPref)
Box 2, 1, 24, 80
COLOR colors(5, ColorPref), colors(4, ColorPref)
LOCATE 1, 1: PRINT SPACE$(80)
LOCATE 1, 4: PRINT "Account Editor";
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE 3, 2: PRINT "No│ Account Title │ Description │A/L"
LOCATE 4, 2: PRINT "──┼────────────────────┼──────────────────────────────────────────────────┼───"
u$ = "##│\ \│\ \│ ! "
FOR a = 5 TO 23
LOCATE a, 2
X = a - 4
PRINT USING u$; X; account(X).Title; account(X).Desc; account(X).AType;
NEXT a
'Initialize variables
help$(1) = " Account name | <F2=Save and Exit> <Escape=Abort>"
help$(2) = " Account description | <F2=Save and Exit> <Escape=Abort>"
help$(3) = " Account type (A = Asset, L = Liability) | <F2=Save and Exit> <Escape=Abort>"
col(1) = 5: col(2) = 26: col(3) = 78
Vis(1) = 20: Vis(2) = 50: Vis(3) = 1
Max(1) = 20: Max(2) = 50: Max(3) = 1
FOR a = 1 TO 19
edit$(a, 1) = account(a).Title
edit$(a, 2) = account(a).Desc
edit$(a, 3) = account(a).AType
NEXT a
finished = FALSE
CurrRow = 1
CurrCol = 1
PrintHelpLine help$(CurrCol)
'Loop until F2 or <ESC> is pressed
DO
GOSUB EditAccountsShowCursor 'Show Cursor
DO 'Wait for key
Kbd$ = INKEY$
LOOP UNTIL Kbd$ <> ""
IF Kbd$ >= " " AND Kbd$ < "~" THEN 'If legal, edit item
GOSUB EditAccountsEditItem
END IF
GOSUB EditAccountsHideCursor 'Hide Cursor so it can move
'If it needs to
SELECT CASE Kbd$
CASE CHR$(0) + "H" 'Up Arrow
CurrRow = (CurrRow + 17) MOD 19 + 1
CASE CHR$(0) + "P" 'Down Arrow
CurrRow = (CurrRow) MOD 19 + 1
CASE CHR$(0) + "K", CHR$(0) + CHR$(15) 'Left or Shift+Tab
CurrCol = (CurrCol + 1) MOD 3 + 1
PrintHelpLine help$(CurrCol)
CASE CHR$(0) + "M", CHR$(9) 'Right or Tab
CurrCol = (CurrCol) MOD 3 + 1
PrintHelpLine help$(CurrCol)
CASE CHR$(0) + "<" 'F2
finished = TRUE
Save = TRUE
CASE CHR$(27) 'Esc
finished = TRUE
Save = FALSE
CASE CHR$(13) 'Return
CASE ELSE
BEEP
END SELECT
LOOP UNTIL finished
IF Save THEN
GOSUB EditAccountsSaveData
END IF
EXIT SUB
EditAccountsShowCursor:
COLOR colors(8, ColorPref), colors(9, ColorPref)
LOCATE CurrRow + 4, col(CurrCol)
PRINT LEFT$(edit$(CurrRow, CurrCol), Vis(CurrCol));
RETURN
EditAccountsEditItem:
COLOR colors(8, ColorPref), colors(9, ColorPref)
ok = FALSE
start$ = Kbd$
DO
Kbd$ = GetString$(CurrRow + 4, col(CurrCol), start$, end$, Vis(CurrCol), Max(CurrCol))
edit$(CurrRow, CurrCol) = LEFT$(end$ + SPACE$(Max(CurrCol)), Max(CurrCol))
start$ = ""
IF CurrCol = 3 THEN
X$ = UCASE$(end$)
IF X$ = "A" OR X$ = "L" OR X$ = "" OR X$ = " " THEN
ok = TRUE
IF X$ = "" THEN X$ = " "
edit$(CurrRow, CurrCol) = X$
ELSE
BEEP
END IF
ELSE
ok = TRUE
END IF
LOOP UNTIL ok
RETURN
EditAccountsHideCursor:
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE CurrRow + 4, col(CurrCol)
PRINT LEFT$(edit$(CurrRow, CurrCol), Vis(CurrCol));
RETURN
EditAccountsSaveData:
FOR a = 1 TO 19
account(a).Title = edit$(a, 1)
account(a).Desc = edit$(a, 2)
account(a).AType = edit$(a, 3)
NEXT a
SaveState
RETURN
END SUB
'EditTrans:
' This is the full-screen editor which allows you to enter and change
' transactions
SUB EditTrans (item)
'Stores info about each column
REDIM help$(6), col(6), Vis(6), Max(6), CurrString$(3), CurrFig#(5)
'Array to keep the current balance at all the transactions
REDIM Balance#(1000)
'Open random access file
file$ = "money." + Cvit$(item)
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 8 AS IoDate$, 10 AS IoRef$, 50 AS IoDesc$, 8 AS IoFig1$, 8 AS IoFig2$
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
'Initialize variables
CurrString$(1) = ""
CurrString$(2) = ""
CurrString$(3) = ""
CurrFig#(4) = 0
CurrFig#(5) = 0
GET #1, 1
IF valid$ <> "THISISVALID" THEN
LSET IoDate$ = ""
LSET IoRef$ = ""
LSET IoDesc$ = ""
LSET IoFig1$ = MKD$(0)
LSET IoFig2$ = MKD$(0)
PUT #1, 2
LSET valid$ = "THISISVALID"
LSET IoMaxRecord$ = "1"
LSET IoBalance$ = MKD$(0)
PUT #1, 1
END IF
MaxRecord = VAL(IoMaxRecord$)
Balance#(0) = 0
a = 1
WHILE a <= MaxRecord
GET #1, a + 1
Balance#(a) = Balance#(a - 1) + CVD(IoFig1$) - CVD(IoFig2$)
a = a + 1
WEND
GOSUB EditTransWriteBalance
help$(1) = "Date of transaction (mm/dd/yy) "
help$(2) = "Transaction reference number "
help$(3) = "Transaction description "
help$(4) = "Increase asset or debt value "
help$(5) = "Decrease asset or debt value "
col(1) = 2
col(2) = 11
col(3) = 18
col(4) = 44
col(5) = 55
Vis(1) = 8
Vis(2) = 6
Vis(3) = 25
Vis(4) = 10
Vis(5) = 10
Max(1) = 8
Max(2) = 6
Max(3) = 25
Max(4) = 10
Max(5) = 10
'Draw Screen
COLOR colors(7, ColorPref), colors(4, ColorPref)
Box 2, 1, 24, 80
COLOR colors(5, ColorPref), colors(4, ColorPref)
LOCATE 1, 1: PRINT SPACE$(80);
LOCATE 1, 4: PRINT "Transaction Editor: " + Trim$(account(item).Title);
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE 3, 2: PRINT " Date │ Ref# │ Description │ Increase │ Decrease │ Balance "
LOCATE 4, 2: PRINT "────────┼──────┼─────────────────────────┼──────────┼──────────┼──────────────"
u$ = "\ \│\ \│\ \│"
u1$ = " │ │ │ │ │ "
u1x$ = "▀▀▀▀▀▀▀▀│▀▀▀▀▀▀│▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀│▀▀▀▀▀▀▀▀▀▀│▀▀▀▀▀▀▀▀▀▀│▀▀▀▀▀▀▀▀▀▀▀▀▀▀"
u2$ = "###,###.##"
u3$ = "###,###,###.##"
u4$ = " "
CurrTopline = 1
GOSUB EditTransPrintWholeScreen
CurrRow = 1
CurrCol = 1
PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>"
GOSUB EditTransGetLine
finished = FALSE
'Loop until <F2> is pressed
DO
GOSUB EditTransShowCursor 'Show Cursor, Wait for key
DO: Kbd$ = INKEY$: LOOP UNTIL Kbd$ <> ""
GOSUB EditTransHideCursor
IF Kbd$ >= " " AND Kbd$ < "~" OR Kbd$ = CHR$(8) THEN 'If legal key, edit item
GOSUB EditTransEditItem
END IF
SELECT CASE Kbd$ 'Handle Special keys
CASE CHR$(0) + "H" 'up arrow
GOSUB EditTransMoveUp
CASE CHR$(0) + "P" 'Down arrow
GOSUB EditTransMoveDown
CASE CHR$(0) + "K", CHR$(0) + CHR$(15) 'Left Arrow,BackTab
CurrCol = (CurrCol + 3) MOD 5 + 1
PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>"
CASE CHR$(0) + "M", CHR$(9) 'Right Arrow,Tab
CurrCol = (CurrCol) MOD 5 + 1
PrintHelpLine help$(CurrCol) + "| <F2=Save and Exit> <F9=Insert> <F10=Delete>"
CASE CHR$(0) + "G" 'Home
CurrCol = 1
CASE CHR$(0) + "O" 'End
CurrCol = 5
CASE CHR$(0) + "I" 'Page Up
CurrRow = 1
CurrTopline = CurrTopline - 19
IF CurrTopline < 1 THEN
CurrTopline = 1
END IF
GOSUB EditTransPrintWholeScreen
GOSUB EditTransGetLine
CASE CHR$(0) + "Q" 'Page Down
CurrRow = 1
CurrTopline = CurrTopline + 19
IF CurrTopline > MaxRecord THEN
CurrTopline = MaxRecord
END IF
GOSUB EditTransPrintWholeScreen
GOSUB EditTransGetLine
CASE CHR$(0) + "<" 'F2
finished = TRUE
CASE CHR$(0) + "C" 'F9
GOSUB EditTransAddRecord
CASE CHR$(0) + "D" 'F10
GOSUB EditTransDeleteRecord
CASE CHR$(13) 'Enter
CASE ELSE
BEEP
END SELECT
LOOP UNTIL finished
CLOSE
EXIT SUB
EditTransShowCursor:
COLOR colors(8, ColorPref), colors(9, ColorPref)
LOCATE CurrRow + 4, col(CurrCol)
SELECT CASE CurrCol
CASE 1, 2, 3
PRINT LEFT$(CurrString$(CurrCol), Vis(CurrCol));
CASE 4
IF CurrFig#(4) <> 0 THEN
PRINT USING u2$; CurrFig#(4);
ELSE
PRINT SPACE$(Vis(CurrCol));
END IF
CASE 5
IF CurrFig#(5) <> 0 THEN
PRINT USING u2$; CurrFig#(5);
ELSE
PRINT SPACE$(Vis(CurrCol));
END IF
END SELECT
RETURN
EditTransHideCursor:
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE CurrRow + 4, col(CurrCol)
SELECT CASE CurrCol
CASE 1, 2, 3
PRINT LEFT$(CurrString$(CurrCol), Vis(CurrCol));
CASE 4
IF CurrFig#(4) <> 0 THEN
PRINT USING u2$; CurrFig#(4);
ELSE
PRINT SPACE$(Vis(CurrCol));
END IF
CASE 5
IF CurrFig#(5) <> 0 THEN
PRINT USING u2$; CurrFig#(5);
ELSE
PRINT SPACE$(Vis(CurrCol));
END IF
END SELECT
RETURN
EditTransEditItem:
CurrRecord = CurrTopline + CurrRow - 1
COLOR colors(8, ColorPref), colors(9, ColorPref)
SELECT CASE CurrCol
CASE 1, 2, 3
Kbd$ = GetString$(CurrRow + 4, col(CurrCol), Kbd$, new$, Vis(CurrCol), Max(CurrCol))
CurrString$(CurrCol) = new$
GOSUB EditTransPutLine
GOSUB EditTransGetLine
CASE 4
start$ = Kbd$
DO
Kbd$ = GetString$(CurrRow + 4, col(4), start$, new$, Vis(4), Max(4))
new4# = VAL(new$)
start$ = ""
LOOP WHILE new4# >= 999999.99# OR new4# < 0
a = CurrRecord
WHILE a <= MaxRecord
Balance#(a) = Balance#(a) + new4# - CurrFig#(4) + CurrFig#(5)
a = a + 1
WEND
CurrFig#(4) = new4#
CurrFig#(5) = 0
GOSUB EditTransPutLine
GOSUB EditTransGetLine
GOSUB EditTransPrintBalances
GOSUB EditTransWriteBalance
CASE 5
start$ = Kbd$
DO
Kbd$ = GetString$(CurrRow + 4, col(5), start$, new$, Vis(5), Max(5))
new5# = VAL(new$)
start$ = ""
LOOP WHILE new5# >= 999999.99# OR new5# < 0
a = CurrRecord
WHILE a <= MaxRecord
Balance#(a) = Balance#(a) - new5# + CurrFig#(5) - CurrFig#(4)
a = a + 1
WEND
CurrFig#(4) = 0
CurrFig#(5) = new5#
GOSUB EditTransPutLine
GOSUB EditTransGetLine
GOSUB EditTransPrintBalances
GOSUB EditTransWriteBalance
CASE ELSE
END SELECT
GOSUB EditTransPrintLine
RETURN
EditTransMoveUp:
IF CurrRow = 1 THEN
IF CurrTopline = 1 THEN
BEEP
ELSE
ScrollDown
CurrTopline = CurrTopline - 1
GOSUB EditTransGetLine
GOSUB EditTransPrintLine
END IF
ELSE
CurrRow = CurrRow - 1
GOSUB EditTransGetLine
END IF
RETURN
EditTransMoveDown:
IF (CurrRow + CurrTopline - 1) >= MaxRecord THEN
BEEP
ELSE
IF CurrRow = 19 THEN
ScrollUp
CurrTopline = CurrTopline + 1
GOSUB EditTransGetLine
GOSUB EditTransPrintLine
ELSE
CurrRow = CurrRow + 1
GOSUB EditTransGetLine
END IF
END IF
RETURN
EditTransPrintLine:
COLOR colors(7, ColorPref), colors(4, ColorPref)
CurrRecord = CurrTopline + CurrRow - 1
LOCATE CurrRow + 4, 2
IF CurrRecord = MaxRecord + 1 THEN
PRINT u1x$;
ELSEIF CurrRecord > MaxRecord THEN
PRINT u1$;
ELSE
PRINT USING u$; CurrString$(1); CurrString$(2); CurrString$(3);
IF CurrFig#(4) = 0 AND CurrFig#(5) = 0 THEN
PRINT USING u4$ + "│" + u4$ + "│" + u3$; Balance#(CurrRecord)
ELSEIF CurrFig#(5) = 0 THEN
PRINT USING u2$ + "│" + u4$ + "│" + u3$; CurrFig#(4); Balance#(CurrRecord)
ELSE
PRINT USING u4$ + "│" + u2$ + "│" + u3$; CurrFig#(5); Balance#(CurrRecord)
END IF
END IF
RETURN
EditTransPrintBalances:
COLOR colors(7, ColorPref), colors(4, ColorPref)
FOR a = 1 TO 19
CurrRecord = CurrTopline + a - 1
IF CurrRecord <= MaxRecord THEN
LOCATE 4 + a, 66
PRINT USING u3$; Balance#(CurrTopline + a - 1);
END IF
NEXT a
RETURN
EditTransDeleteRecord:
IF MaxRecord = 1 THEN
BEEP
ELSE
CurrRecord = CurrTopline + CurrRow - 1
MaxRecord = MaxRecord - 1
a = CurrRecord
WHILE a <= MaxRecord
GET #1, a + 2
PUT #1, a + 1
Balance#(a) = Balance#(a + 1) - CurrFig#(4) + CurrFig#(5)
a = a + 1
WEND
LSET valid$ = "THISISVALID"
LSET IoMaxRecord$ = Cvit$(MaxRecord)
PUT #1, 1
GOSUB EditTransPrintWholeScreen
CurrRecord = CurrTopline + CurrRow - 1
IF CurrRecord > MaxRecord THEN
GOSUB EditTransMoveUp
END IF
GOSUB EditTransGetLine
GOSUB EditTransWriteBalance
END IF
RETURN
EditTransAddRecord:
CurrRecord = CurrTopline + CurrRow - 1
a = MaxRecord
WHILE a > CurrRecord
GET #1, a + 1
PUT #1, a + 2
Balance#(a + 1) = Balance#(a)
a = a - 1
WEND
Balance#(CurrRecord + 1) = Balance#(CurrRecord)
MaxRecord = MaxRecord + 1
LSET IoDate$ = ""
LSET IoRef$ = ""
LSET IoDesc$ = ""
LSET IoFig1$ = MKD$(0)
LSET IoFig2$ = MKD$(0)
PUT #1, CurrRecord + 2
LSET valid$ = "THISISVALID"
LSET IoMaxRecord$ = Cvit$(MaxRecord)
PUT #1, 1
GOSUB EditTransPrintWholeScreen
GOSUB EditTransGetLine
RETURN
EditTransPrintWholeScreen:
temp = CurrRow
FOR CurrRow = 1 TO 19
CurrRecord = CurrTopline + CurrRow - 1
IF CurrRecord <= MaxRecord THEN
GOSUB EditTransGetLine
END IF
GOSUB EditTransPrintLine
NEXT CurrRow
CurrRow = temp
RETURN
EditTransWriteBalance:
GET #1, 1
LSET IoBalance$ = MKD$(Balance#(MaxRecord))
PUT #1, 1
RETURN
EditTransPutLine:
CurrRecord = CurrTopline + CurrRow - 1
LSET IoDate$ = CurrString$(1)
LSET IoRef$ = CurrString$(2)
LSET IoDesc$ = CurrString$(3)
LSET IoFig1$ = MKD$(CurrFig#(4))
LSET IoFig2$ = MKD$(CurrFig#(5))
PUT #1, CurrRecord + 1
RETURN
EditTransGetLine:
CurrRecord = CurrTopline + CurrRow - 1
GET #1, CurrRecord + 1
CurrString$(1) = IoDate$
CurrString$(2) = IoRef$
CurrString$(3) = IoDesc$
CurrFig#(4) = CVD(IoFig1$)
CurrFig#(5) = CVD(IoFig2$)
RETURN
END SUB
'FancyCls:
' Clears screen in the right color, and draws nice dots.
SUB FancyCls (dots, Background)
VIEW PRINT 2 TO 24
COLOR dots, Background
CLS 2
FOR a = 95 TO 1820 STEP 45
row = a / 80 + 1
col = a MOD 80 + 1
LOCATE row, col
PRINT CHR$(250);
NEXT a
VIEW PRINT
END SUB
'GetString$:
' Given a row and col, and an initial string, edit a string
' VIS is the length of the visible field of entry
' MAX is the maximum number of characters allowed in the string
FUNCTION GetString$ (row, col, start$, end$, Vis, Max)
curr$ = Trim$(LEFT$(start$, Max))
IF curr$ = CHR$(8) THEN curr$ = ""
LOCATE , , 1
finished = FALSE
DO
GOSUB GetStringShowText
GOSUB GetStringGetKey
IF LEN(Kbd$) > 1 THEN
finished = TRUE
GetString$ = Kbd$
ELSE
SELECT CASE Kbd$
CASE CHR$(13), CHR$(27), CHR$(9)
finished = TRUE
GetString$ = Kbd$
CASE CHR$(8)
IF curr$ <> "" THEN
curr$ = LEFT$(curr$, LEN(curr$) - 1)
END IF
CASE " " TO "}"
IF LEN(curr$) < Max THEN
curr$ = curr$ + Kbd$
ELSE
BEEP
END IF
CASE ELSE
BEEP
END SELECT
END IF
LOOP UNTIL finished
end$ = curr$
LOCATE , , 0
EXIT FUNCTION
GetStringShowText:
LOCATE row, col
IF LEN(curr$) > Vis THEN
PRINT RIGHT$(curr$, Vis);
ELSE
PRINT curr$; SPACE$(Vis - LEN(curr$));
LOCATE row, col + LEN(curr$)
END IF
RETURN
GetStringGetKey:
Kbd$ = ""
WHILE Kbd$ = ""
Kbd$ = INKEY$
WEND
RETURN
END FUNCTION
'Initialize:
' Read colors in and set up assembly routines
SUB Initialize
WIDTH , 25
VIEW PRINT
FOR ColorSet = 1 TO 4
FOR X = 1 TO 10
READ colors(X, ColorSet)
NEXT X
NEXT ColorSet
LoadState
P = VARPTR(ScrollUpAsm(1))
DEF SEG = VARSEG(ScrollUpAsm(1))
FOR I = 0 TO 13
READ J
POKE (P + I), J
NEXT I
P = VARPTR(ScrollDownAsm(1))
DEF SEG = VARSEG(ScrollDownAsm(1))
FOR I = 0 TO 13
READ J
POKE (P + I), J
NEXT I
DEF SEG
END SUB
'Intro:
' Display introduction screen.
SUB Intro
SCREEN 0
WIDTH 80, 25
COLOR 7, 0
CLS
Center 4, "Q B a s i c"
COLOR 15
Center 5, "▄ ▄ ▄▄▄▄ ▄ ▄ ▄▄▄▄ ▄ ▄ ▄ ▄ ▄▄▄▄ ▄ ▄ ▄▄▄▄ ▄▄▄▄▄ ▄▄▄▄ ▄▄▄▄▄"
Center 6, "█▀▄ ▄▀█ █ █ █▄ █ █ █▄▄▄█ █▀▄ ▄▀█ █ █ █▄ █ █ █ █ █ █ █"
Center 7, "█ ▀ █ █ █ █ ▀▄█ █▀▀▀ █ █ ▀ █ █▀▀█ █ ▀▄█ █▀▀█ █ ▀▀█ █▀▀▀ █▀█▀▀"
Center 8, "█ █ █▄▄█ █ █ █▄▄▄ █ █ █ █ █ █ █ █ █ █▄▄▄█ █▄▄▄ █ ▀▄"
COLOR 7
Center 11, "A Personal Finance Manager written in"
Center 12, "MS-DOS QBasic"
Center 24, "Press any key to continue"
SparklePause
END SUB
'LCenter:
' Center TEXT$ on the line printer
SUB LCenter (text$)
LPRINT TAB(41 - LEN(text$) / 2); text$
END SUB
'LoadState:
' Load color preferences and account info from MONEY.DAT
SUB LoadState
OPEN "money.dat" FOR INPUT AS #1
INPUT #1, ColorPref
FOR a = 1 TO 19
LINE INPUT #1, account(a).Title
LINE INPUT #1, account(a).AType
LINE INPUT #1, account(a).Desc
NEXT a
CLOSE
END SUB
'Menu:
' Handles Menu Selection for a single menu (either sub menu, or menu bar)
' currChoiceX : Number of current choice
' maxChoice : Number of choices in the list
' choice$() : Array with the text of the choices
' itemRow() : Array with the row of the choices
' itemCol() : Array with the col of the choices
' help$() : Array with the help text for each choice
' barMode : Boolean: TRUE = menu bar style, FALSE = drop down style
'
' Returns the number of the choice that was made by changing currChoiceX
' and returns the scan code of the key that was pressed to exit
'
FUNCTION Menu (CurrChoiceX, MaxChoice, choice$(), ItemRow(), ItemCol(), help$(), BarMode)
currChoice = CurrChoiceX
'if in bar mode, color in menu bar, else color box/shadow
'bar mode means you are currently in the menu bar, not a sub menu
IF BarMode THEN
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE 1, 1
PRINT SPACE$(80);
ELSE
FancyCls colors(2, ColorPref), colors(1, ColorPref)
COLOR colors(7, ColorPref), colors(4, ColorPref)
Box ItemRow(1) - 1, ItemCol(1) - 1, ItemRow(MaxChoice) + 1, ItemCol(1) + LEN(choice$(1)) + 1
COLOR colors(10, ColorPref), colors(6, ColorPref)
FOR a = 1 TO MaxChoice + 1
LOCATE ItemRow(1) + a - 1, ItemCol(1) + LEN(choice$(1)) + 2
PRINT CHR$(178); CHR$(178);
NEXT a
LOCATE ItemRow(MaxChoice) + 2, ItemCol(MaxChoice) + 2
PRINT STRING$(LEN(choice$(MaxChoice)) + 2, 178);
END IF
'print the choices
COLOR colors(7, ColorPref), colors(4, ColorPref)
FOR a = 1 TO MaxChoice
LOCATE ItemRow(a), ItemCol(a)
PRINT choice$(a);
NEXT a
finished = FALSE
WHILE NOT finished
GOSUB MenuShowCursor
GOSUB MenuGetKey
GOSUB MenuHideCursor
SELECT CASE Kbd$
CASE CHR$(0) + "H": GOSUB MenuUp
CASE CHR$(0) + "P": GOSUB MenuDown
CASE CHR$(0) + "K": GOSUB MenuLeft
CASE CHR$(0) + "M": GOSUB MenuRight
CASE CHR$(13): GOSUB MenuEnter
CASE CHR$(27): GOSUB MenuEscape
CASE ELSE: BEEP
END SELECT
WEND
Menu = currChoice
EXIT FUNCTION
MenuEnter:
finished = TRUE
RETURN
MenuEscape:
currChoice = 0
finished = TRUE
RETURN
MenuUp:
IF BarMode THEN
BEEP
ELSE
currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1
END IF
RETURN
MenuLeft:
IF BarMode THEN
currChoice = (currChoice + MaxChoice - 2) MOD MaxChoice + 1
ELSE
currChoice = -2
finished = TRUE
END IF
RETURN
MenuRight:
IF BarMode THEN
currChoice = (currChoice) MOD MaxChoice + 1
ELSE
currChoice = -3
finished = TRUE
END IF
RETURN
MenuDown:
IF BarMode THEN
finished = TRUE
ELSE
currChoice = (currChoice) MOD MaxChoice + 1
END IF
RETURN
MenuShowCursor:
COLOR colors(8, ColorPref), colors(9, ColorPref)
LOCATE ItemRow(currChoice), ItemCol(currChoice)
PRINT choice$(currChoice);
PrintHelpLine help$(currChoice)
RETURN
MenuGetKey:
Kbd$ = ""
WHILE Kbd$ = ""
Kbd$ = INKEY$
WEND
RETURN
MenuHideCursor:
COLOR colors(7, ColorPref), colors(4, ColorPref)
LOCATE ItemRow(currChoice), ItemCol(currChoice)
PRINT choice$(currChoice);
RETURN
END FUNCTION
'MenuSystem:
' Main routine that controls the program. Uses the MENU function
' to implement menu system and calls the appropriate function to handle
' the user's selection
SUB MenuSystem
DIM choice$(20), menuRow(20), menuCol(20), help$(20)
LOCATE , , 0
choice = 1
finished = FALSE
WHILE NOT finished
GOSUB MenuSystemMain
subchoice = -1
WHILE subchoice < 0
SELECT CASE choice
CASE 1: GOSUB MenuSystemFile
CASE 2: GOSUB MenuSystemEdit
CASE 3: GOSUB MenuSystemAccount
CASE 4: GOSUB MenuSystemReport
CASE 5: GOSUB MenuSystemColors
END SELECT
FancyCls colors(2, ColorPref), colors(1, ColorPref)
SELECT CASE subchoice
CASE -2: choice = (choice + 3) MOD 5 + 1
CASE -3: choice = (choice) MOD 5 + 1
END SELECT
WEND
WEND
EXIT SUB
MenuSystemMain:
FancyCls colors(2, ColorPref), colors(1, ColorPref)
COLOR colors(7, ColorPref), colors(4, ColorPref)
Box 9, 19, 14, 61
Center 11, "Use arrow keys to navigate menu system"
Center 12, "Press Enter to select a menu item"
choice$(1) = " File "
choice$(2) = " Accounts "
choice$(3) = " Transactions "
choice$(4) = " Reports "
choice$(5) = " Colors "
menuRow(1) = 1: menuCol(1) = 2
menuRow(2) = 1: menuCol(2) = 8
menuRow(3) = 1: menuCol(3) = 18
menuRow(4) = 1: menuCol(4) = 32
menuRow(5) = 1: menuCol(5) = 41
help$(1) = "Exit the Money Manager"
help$(2) = "Add/edit/delete accounts"
help$(3) = "Add/edit/delete account transactions"
help$(4) = "View and print reports"
help$(5) = "Set screen colors"
DO
NewChoice = Menu((choice), 5, choice$(), menuRow(), menuCol(), help$(), TRUE)
LOOP WHILE NewChoice = 0
choice = NewChoice
RETURN
MenuSystemFile:
choice$(1) = " Exit "
menuRow(1) = 3: menuCol(1) = 2
help$(1) = "Exit the Money Manager"
subchoice = Menu(1, 1, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice
CASE 1: finished = TRUE
CASE ELSE
END SELECT
RETURN
MenuSystemEdit:
choice$(1) = " Edit Account Titles "
menuRow(1) = 3: menuCol(1) = 8
help$(1) = "Add/edit/delete accounts"
subchoice = Menu(1, 1, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice
CASE 1: EditAccounts
CASE ELSE
END SELECT
RETURN
MenuSystemAccount:
FOR a = 1 TO 19
IF Trim$(account(a).Title) = "" THEN
choice$(a) = RIGHT$(STR$(a), 2) + ". ------------------- "
ELSE
choice$(a) = RIGHT$(STR$(a), 2) + ". " + account(a).Title
END IF
menuRow(a) = a + 2
menuCol(a) = 19
help$(a) = RTRIM$(account(a).Desc)
NEXT a
subchoice = Menu(1, 19, choice$(), menuRow(), menuCol(), help$(), FALSE)
IF subchoice > 0 THEN
EditTrans (subchoice)
END IF
RETURN
MenuSystemReport:
choice$(1) = " Net Worth Report "
menuRow(1) = 3: menuCol(1) = 32
help$(1) = "View and print net worth report"
FOR a = 1 TO 19
IF Trim$(account(a).Title) = "" THEN
choice$(a + 1) = RIGHT$(STR$(a), 2) + ". ------------------- "
ELSE
choice$(a + 1) = RIGHT$(STR$(a), 2) + ". " + account(a).Title
END IF
menuRow(a + 1) = a + 3
menuCol(a + 1) = 32
help$(a + 1) = "Print " + RTRIM$(account(a).Title) + " transaction summary"
NEXT a
subchoice = Menu(1, 20, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice
CASE 1
NetWorthReport
CASE 2 TO 20
TransactionSummary (subchoice - 1)
CASE ELSE
END SELECT
RETURN
MenuSystemColors:
choice$(1) = " Monochrome Scheme "
choice$(2) = " Cyan/Blue Scheme "
choice$(3) = " Blue/Cyan Scheme "
choice$(4) = " Red/Grey Scheme "
menuRow(1) = 3: menuCol(1) = 41
menuRow(2) = 4: menuCol(2) = 41
menuRow(3) = 5: menuCol(3) = 41
menuRow(4) = 6: menuCol(4) = 41
help$(1) = "Color scheme for monochrome and LCD displays"
help$(2) = "Color scheme featuring cyan"
help$(3) = "Color scheme featuring blue"
help$(4) = "Color scheme featuring red"
subchoice = Menu(1, 4, choice$(), menuRow(), menuCol(), help$(), FALSE)
SELECT CASE subchoice
CASE 1 TO 4
ColorPref = subchoice
SaveState
CASE ELSE
END SELECT
RETURN
END SUB
'NetWorthReport:
' Prints net worth report to screen and printer
SUB NetWorthReport
DIM assetIndex(19), liabilityIndex(19)
maxAsset = 0
maxLiability = 0
FOR a = 1 TO 19
IF account(a).AType = "A" THEN
maxAsset = maxAsset + 1
assetIndex(maxAsset) = a
ELSEIF account(a).AType = "L" THEN
maxLiability = maxLiability + 1
liabilityIndex(maxLiability) = a
END IF
NEXT a
'Loop until <F2> is pressed
finished = FALSE
DO
u1$ = "\ \$$###,###,###.##"
u2$ = "\ \+$$#,###,###,###.##"
COLOR colors(5, ColorPref), colors(4, ColorPref)
LOCATE 1, 1: PRINT SPACE$(80);
LOCATE 1, 4: PRINT "Net Worth Report: " + DATE$;
PrintHelpLine "<F2=Exit> <F3=Print Report>"
COLOR colors(7, ColorPref), colors(4, ColorPref)
Box 2, 1, 24, 40
Box 2, 41, 24, 80
LOCATE 2, 16: PRINT " ASSETS "
assetTotal# = 0
a = 1
count1 = 1
WHILE a <= maxAsset
file$ = "money." + Cvit$(assetIndex(a))
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
GET #1, 1
IF valid$ = "THISISVALID" THEN
LOCATE 2 + count1, 3: PRINT USING u1$; account(assetIndex(a)).Title; CVD(IoBalance$)
assetTotal# = assetTotal# + CVD(IoBalance$)
count1 = count1 + 1
END IF
CLOSE
a = a + 1
WEND
LOCATE 2, 55: PRINT " LIABILITIES "
liabilityTotal# = 0
a = 1
count2 = 1
WHILE a <= maxLiability
file$ = "money." + Cvit$(liabilityIndex(a))
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
GET #1, 1
IF valid$ = "THISISVALID" THEN
LOCATE 2 + count2, 43: PRINT USING u1$; account(liabilityIndex(a)).Title; CVD(IoBalance$)
liabilityTotal# = liabilityTotal# + CVD(IoBalance$)
count2 = count2 + 1
END IF
CLOSE
a = a + 1
WEND
IF count2 > count1 THEN count1 = count2
LOCATE 2 + count1, 25: PRINT "--------------"
LOCATE 2 + count1, 65: PRINT "--------------"
LOCATE 3 + count1, 3: PRINT USING u2$; "Total assets"; assetTotal#;
LOCATE 3 + count1, 43: PRINT USING u2$; "Total liabilities"; liabilityTotal#
COLOR colors(5, ColorPref), colors(4, ColorPref)
LOCATE 1, 43: PRINT USING u2$; " NET WORTH:"; assetTotal# - liabilityTotal#
DO: Kbd$ = INKEY$: LOOP UNTIL Kbd$ <> ""
SELECT CASE Kbd$ 'Handle Special keys
CASE CHR$(0) + "<" 'F2
finished = TRUE
CASE CHR$(0) + "=" 'F3
GOSUB NetWorthReportPrint
CASE ELSE
BEEP
END SELECT
LOOP UNTIL finished
EXIT SUB
NetWorthReportPrint:
PrintHelpLine ""
Box 8, 20, 14, 62
Center 10, "Prepare printer on LPT1 for report"
Center 12, "Hit <Enter> to print, or <Esc> to abort"
DO: Kbd$ = INKEY$: LOOP WHILE Kbd$ <> CHR$(13) AND Kbd$ <> CHR$(27)
IF Kbd$ = CHR$(13) THEN
Box 8, 20, 14, 62
Center 11, "Printing report..."
u0$ = " \ \ "
u1$ = " \ \ $$###,###,###.##"
u2$ = " --------------"
u3$ = " ============="
u4$ = " \ \+$$#,###,###,###.##"
PrintErr = FALSE
ON ERROR GOTO ErrorTrap ' test if printer is connected
LPRINT
IF PrintErr = FALSE THEN
LPRINT : LPRINT : LPRINT : LPRINT : LPRINT
LCenter "Q B a s i c"
LCenter "M O N E Y M A N A G E R"
LPRINT : LPRINT
LCenter "NET WORTH REPORT: " + DATE$
LCenter "-------------------------------------------"
LPRINT USING u0$; "ASSETS:"
assetTotal# = 0
a = 1
WHILE a <= maxAsset
file$ = "money." + Cvit$(assetIndex(a))
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
GET #1, 1
IF valid$ = "THISISVALID" THEN
LPRINT USING u1$; account(assetIndex(a)).Title; CVD(IoBalance$)
assetTotal# = assetTotal# + CVD(IoBalance$)
END IF
CLOSE #1
a = a + 1
WEND
LPRINT u2$
LPRINT USING u4$; "Total assets"; assetTotal#
LPRINT
LPRINT
LPRINT USING u0$; "LIABILITIES:"
liabilityTotal# = 0
a = 1
WHILE a <= maxLiability
file$ = "money." + Cvit$(liabilityIndex(a))
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
GET #1, 1
IF valid$ = "THISISVALID" THEN
LPRINT USING u1$; account(liabilityIndex(a)).Title; CVD(IoBalance$)
liabilityTotal# = liabilityTotal# + CVD(IoBalance$)
END IF
CLOSE #1
a = a + 1
WEND
LPRINT u2$
LPRINT USING u4$; "Total liabilities"; liabilityTotal#
LPRINT
LPRINT
LPRINT u3$
LPRINT USING u4$; "NET WORTH"; assetTotal# - liabilityTotal#
LCenter "-------------------------------------------"
LPRINT : LPRINT : LPRINT
END IF
ON ERROR GOTO 0
END IF
RETURN
END SUB
'PrintHelpLine:
' Prints help text on the bottom row in the proper color
SUB PrintHelpLine (help$)
COLOR colors(5, ColorPref), colors(4, ColorPref)
LOCATE 25, 1
PRINT SPACE$(80);
Center 25, help$
END SUB
'SaveState:
' Save color preference and account information to "MONEY.DAT" data file.
SUB SaveState
OPEN "money.dat" FOR OUTPUT AS #2
PRINT #2, ColorPref
FOR a = 1 TO 19
PRINT #2, account(a).Title
PRINT #2, account(a).AType
PRINT #2, account(a).Desc
NEXT a
CLOSE #2
END SUB
'ScrollDown:
' Call the assembly program to scroll the screen down
SUB ScrollDown
DEF SEG = VARSEG(ScrollDownAsm(1))
CALL Absolute(VARPTR(ScrollDownAsm(1)))
DEF SEG
END SUB
'ScrollUp:
' Calls the assembly program to scroll the screen up
SUB ScrollUp
DEF SEG = VARSEG(ScrollUpAsm(1))
CALL Absolute(VARPTR(ScrollUpAsm(1)))
DEF SEG
END SUB
'SparklePause:
' Creates flashing border for intro screen
SUB SparklePause
COLOR 4, 0
a$ = "* * * * * * * * * * * * * * * * * "
WHILE INKEY$ <> "": WEND 'Clear keyboard buffer
WHILE INKEY$ = ""
FOR a = 1 TO 5
LOCATE 1, 1 'print horizontal sparkles
PRINT MID$(a$, a, 80);
LOCATE 22, 1
PRINT MID$(a$, 6 - a, 80);
FOR b = 2 TO 21 'Print Vertical sparkles
c = (a + b) MOD 5
IF c = 1 THEN
LOCATE b, 80
PRINT "*";
LOCATE 23 - b, 1
PRINT "*";
ELSE
LOCATE b, 80
PRINT " ";
LOCATE 23 - b, 1
PRINT " ";
END IF
NEXT b
NEXT a
WEND
END SUB
'TransactionSummary:
' Print transaction summary to line printer
SUB TransactionSummary (item)
FancyCls colors(2, ColorPref), colors(1, ColorPref)
PrintHelpLine ""
Box 8, 20, 14, 62
Center 10, "Prepare printer on LPT1 for report"
Center 12, "Hit <Enter> to print, or <Esc> to abort"
DO: Kbd$ = INKEY$: LOOP WHILE Kbd$ <> CHR$(13) AND Kbd$ <> CHR$(27)
IF Kbd$ = CHR$(13) THEN
Box 8, 20, 14, 62
Center 11, "Printing report..."
PrintErr = FALSE
ON ERROR GOTO ErrorTrap ' test if printer is connected
LPRINT
IF PrintErr = FALSE THEN
PRINT
LPRINT : LPRINT : LPRINT : LPRINT : LPRINT
LCenter "Q B a s i c"
LCenter "M O N E Y M A N A G E R"
LPRINT : LPRINT
LCenter "Transaction summary: " + Trim$(account(item).Title)
LCenter DATE$
LPRINT
u5$ = "--------|------|------------------------|----------|----------|--------------"
LPRINT u5$
LPRINT " Date | Ref# | Description | Increase | Decrease | Balance "
LPRINT u5$
u0$ = "\ \|\ \|\ \|"
u2$ = "###,###.##"
u3$ = "###,###,###.##"
u4$ = " "
file$ = "money." + Cvit$(item)
OPEN file$ FOR RANDOM AS #1 LEN = 84
FIELD #1, 8 AS IoDate$, 10 AS IoRef$, 50 AS IoDesc$, 8 AS IoFig1$, 8 AS IoFig2$
FIELD #1, 11 AS valid$, 5 AS IoMaxRecord$, 8 AS IoBalance$
GET #1, 1
IF valid$ = "THISISVALID" THEN
Balance# = 0
MaxRecord = VAL(IoMaxRecord$)
CurrRecord = 1
WHILE CurrRecord <= MaxRecord
GET #1, CurrRecord + 1
Fig1# = CVD(IoFig1$)
Fig2# = CVD(IoFig2$)
LPRINT USING u0$; IoDate$; IoRef$; IoDesc$;
IF Fig2# = 0 AND Fig1# = 0 THEN
LPRINT USING u4$ + "|" + u4$ + "|" + u3$; Balance#
ELSEIF Fig2# = 0 THEN
Balance# = Balance# + Fig1#
LPRINT USING u2$ + "|" + u4$ + "|" + u3$; Fig1#; Balance#
ELSE
Balance# = Balance# - Fig2#
LPRINT USING u4$ + "|" + u2$ + "|" + u3$; Fig2#; Balance#
END IF
CurrRecord = CurrRecord + 1
WEND
LPRINT u5$
LPRINT : LPRINT
END IF
ON ERROR GOTO 0
END IF
CLOSE
END IF
END SUB
'Trin$:
' Remove null and spaces from the end of a string.
FUNCTION Trim$ (X$)
IF X$ = "" THEN
Trim$ = ""
ELSE
lastChar = 0
FOR a = 1 TO LEN(X$)
y$ = MID$(X$, a, 1)
IF y$ <> CHR$(0) AND y$ <> " " THEN
lastChar = a
END IF
NEXT a
Trim$ = LEFT$(X$, lastChar)
END IF
END FUNCTION